You're reading an pre-release version of this documentation.
For the latest stable release version, please have a look at master.

SpinalEnum

Description

The Enumeration type corresponds to a list of named values.

Declaration

The declaration of an enumerated data type is as follows:

object Enumeration extends SpinalEnum {
  val element0, element1, ..., elementN = newElement()
}

For the example above, the default encoding is used. The native enumeration type is used for VHDL and a binary encoding is used for Verilog.

The enumeration encoding can be forced by defining the enumeration as follows:

object Enumeration extends SpinalEnum(defaultEncoding=encodingOfYourChoice) {
  val element0, element1, ..., elementN = newElement()
}

Note

If you want to define an enumeration as in/out for a given component, you have to do as following: in(MyEnum()) or out(MyEnum())

Encoding

The following enumeration encodings are supported:

Encoding

Bit width

Description

native

Use the VHDL enumeration system, this is the default encoding

binarySequential

log2Up(stateCount)

Use Bits to store states in declaration order (value from 0 to n-1)

binaryOneHot

stateCount

Use Bits to store state. Each bit corresponds to one state, only one bit is set at a time in the hardware encoded state representation.

graySequential

log2Up(stateCount)

Encode index (numbers as if using binarySequential) as binary gray code.

Custom encodings can be performed in two different ways: static or dynamic.

/*
 * Static encoding
 */
object MyEnumStatic extends SpinalEnum {
  val e0, e1, e2, e3 = newElement()
  defaultEncoding = SpinalEnumEncoding("staticEncoding")(
    e0 -> 0,
    e1 -> 2,
    e2 -> 3,
    e3 -> 7)
}

/*
 * Dynamic encoding with the function :  _ * 2 + 1
 *   e.g. : e0 => 0 * 2 + 1 = 1
 *          e1 => 1 * 2 + 1 = 3
 *          e2 => 2 * 2 + 1 = 5
 *          e3 => 3 * 2 + 1 = 7
 */
val encoding = SpinalEnumEncoding("dynamicEncoding", _ * 2 + 1)

object MyEnumDynamic extends SpinalEnum(encoding) {
  val e0, e1, e2, e3 = newElement()
}

Example

Instantiate an enumerated signal and assign a value to it:

object UartCtrlTxState extends SpinalEnum {
  val sIdle, sStart, sData, sParity, sStop = newElement()
}

val stateNext = UartCtrlTxState()
stateNext := UartCtrlTxState.sIdle

// You can also import the enumeration to have visibility of its elements
import UartCtrlTxState._
stateNext := sIdle

Operators

The following operators are available for the Enumeration type:

Comparison

Operator

Description

Return type

x === y

Equality

Bool

x =/= y

Inequality

Bool

import UartCtrlTxState._

val stateNext = UartCtrlTxState()
stateNext := sIdle

when(stateNext === sStart) {
  ...
}

switch(stateNext) {
  is(sIdle) {
    ...
  }
  is(sStart) {
    ...
  }
  ...
}

Types

In order to use your enums, for example in a function, you may need its type.

The value type (e.g. sIdle’s type) is

spinal.core.SpinalEnumElement[UartCtrlTxState.type]

or equivalently

UartCtrlTxState.E

The bundle type (e.g. stateNext’s type) is

spinal.core.SpinalEnumCraft[UartCtrlTxState.type]

or equivalently

UartCtrlTxState.C

Type cast

Operator

Description

Return

x.asBits

Binary cast to Bits

Bits(w(x) bits)

x.asBits.asUInt

Binary cast to UInt

UInt(w(x) bits)

x.asBits.asSInt

Binary cast to SInt

SInt(w(x) bits)

e.assignFromBits(bits)

Bits cast to enum

MyEnum()

import UartCtrlTxState._

val stateNext = UartCtrlTxState()
myBits := sIdle.asBits

stateNext.assignFromBits(myBits)